package com.sunsharing.transport;

import com.sunsharing.common.Constant;
import com.sunsharing.common.URL;
import com.sunsharing.common.config.NodeModel;
import com.sunsharing.transport.mina.MinaChannel;
import org.apache.log4j.Logger;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 处理通用的心跳等功能
 * User: criss
 * Date: 13-3-31
 * Time: 下午8:33
 * To change this template use File | Settings | File Templates.
 */
public abstract class ConnectClients  {
    static Logger logger = Logger.getLogger(ConnectClients.class);
    //key protocol:ip:client value Socket或者其他框架的IOSession
    static public List<Channel> activeClients = new ArrayList();


    public static List<Channel> searchActiveApiClient(String nodeId)
    {
        String apiIp = nodeId;
        Iterator iter = activeClients.iterator();
        List<Channel> result = new ArrayList<Channel>();
        while (iter.hasNext()) {
            Channel entry = (Channel) iter.next();
            if(entry.url.getIsClient().equals("false") && entry.url.getFromNodeId().startsWith(apiIp) &&
                    !entry.isclose() &&
                    (entry.url.getProtocol().equals("MINA")||entry.url.getProtocol().equals("NETTY")))
            {
                result.add(entry);
            }
        }
        return result;
    }
    public static boolean allSuccessBack(List<URL> success)
    {
        try
        {
            for(Iterator<URL> iter = success.iterator();iter.hasNext();)
            {
                URL url = iter.next();
                Channel r = searchClient(url.getProtocol(),url.getIp(),url.getPort());
                if(r==null)
                {
                    return false;
                }
            }
            return true;
        }catch (Exception e)
        {
            logger.error("aaaa",e);
            return false;
        }
    }


    public static List<Channel> searchActiveClient(String nextNode)
    {
        List<Channel> chs = new ArrayList<Channel>();
        Iterator iter = activeClients.iterator();
        while (iter.hasNext()) {
            Channel entry = (Channel) iter.next();
            if(entry.url.getIsClient().equals("false")  && entry.url.getFromNodeId().equals(nextNode) && !entry.isclose() &&
                    (entry.url.getProtocol().equals("MINA")||entry.url.getProtocol().equals("NETTY")) )
            {
                chs.add(entry);
            }
        }
        return  chs;
    }

    public static List<Channel> searchActive(List<String> nextdNodes)
    {
        List<Channel> chs = new ArrayList<Channel>();
        Iterator iter = activeClients.iterator();
        while (iter.hasNext()) {
            Channel entry = (Channel) iter.next();
            if(entry.url.getIsClient().equals("true")  && nextdNodes.contains(entry.url.getToNodeId())  && !entry.isclose()  )
            {
                chs.add(entry);
            }
        }
        return  chs;
    }

    public static Channel getActiveServerChannel()
    {
        Iterator iter = activeClients.iterator();
        while (iter.hasNext()) {
            LongChannel entry = (LongChannel) iter.next();
            if(entry.isClient() == false  && !entry.isclose() &&
                    (entry.url.getProtocol().equals("MINA")||entry.url.getProtocol().equals("NETTY")) )
            {
                return entry;
            }
        }
        return  null;
    }


    public static Channel searchClient(String protocol,String ip,int port)
    {
        Iterator iter = activeClients.iterator();
        while (iter.hasNext()) {
            Channel entry = (Channel) iter.next();
            if(entry.url.getIsClient().equals("true")  && entry.url.getIp().equals(ip) &&  entry.url.getPort()==(port) &&
                    entry.url.getProtocol().equals(protocol) )
            {
                return entry;
            }
        }
        return  null;
    }

    public static Channel seachClient(String protocol,String fromNode,String toNode)
    {
        Iterator iter = activeClients.iterator();
        while (iter.hasNext()) {
            Channel entry = (Channel) iter.next();
            if(entry.url.getIsClient().equals("true")  && entry.url.getFromNodeId().equals(fromNode) &&  entry.url.getToNodeId().equals(toNode) &&
                    entry.url.getProtocol().equals(protocol) )
            {
                return entry;
            }
        }
        return  null;
    }

    public static void watch()
    {
        Iterator iter = activeClients.iterator();
        StringBuffer str = new StringBuffer();
        str.append("\n");
        while (iter.hasNext()) {
            str.append("------------------&&&&&begin&&&&&-----------------------\n");
            Channel entry = (Channel) iter.next();
            String status = "";
            if(!entry.isclose())
            {
                status = "正常";
            } else
            {
                status = "异常";
            }
            if(entry.url.getIsClient().equals("true"))
            {

                str.append("连接其他服务器:" + entry.url.toString() + ",状态：" + status+"\n");
                str.append(entry.toMonitor());
            } else
            {
                str.append("被连接客户端:"+entry.url.toString()+",状态："+status+"\n");
                str.append(entry.toMonitor());
            }
            str.append("-----------------&&&&&end&&&&&----------------------\n");
        }
        logger.fatal(str);
    }

    public static Channel searchClient(Channel ch)
    {
        if(activeClients.contains(ch))
        {
             int index = activeClients.indexOf(ch);
            return activeClients.get(index);
        } else
        {
            return null;
        }
    }

    public synchronized static Channel addClient(Channel channel)
    {
        logger.info("添加前------");
        //watch();
        Channel old = searchClient(channel);
        if(old!=null)
        {
            logger.error("结束旧的------"+old.url);
            try
            {
                old.stop();
            }catch (Exception e)
            {
                logger.error("结束channel,i："+old.url+"失败",e);
            }
            old.clone(channel);
            old.restartMailBox();
            logger.info("存在添加后---------");
           // watch();
            return old;
        } else
        {
            activeClients.add(channel);
            //第一次需要初始化
            channel.initMailBox();
            logger.info("初始化添加后-------");
          //  watch();
            return channel;

        }
        //watch();

    }

    public synchronized static void removeClient(Channel channel)
    {
        logger.info("删除------"+channel.url);
        Channel old = searchClient(channel);
        if(old!=null)
        {
            try
            {
                old.stop();
            }catch (Exception e)
            {
                logger.error("结束channel,i："+old.url+"失败",e);
            }
            logger.info("删除Client:" + old.url);
        }
    }


}
